﻿using ProjScan.Config;
using ProjScan.Modules;
using ProjScan.Tools;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace ProjScan.Submodules.Scene_Check
{
    internal class ScenesMapData : ModuleData
    {
        public static readonly ScenesMapData Instance = new ScenesMapData();

        private ScenesCheckConfig scenesCheckConfig = null;

        private Dictionary<string, int> scenesDictionary = new Dictionary<string, int>();

        public string[] scenesList;

        public int Index
        {
            get;
            private set;
        }

        private ScenesMapData()
        {
        }

        public int GetSceneIndex(string scenePath)
        {
            int value = 0;
            if (scenesDictionary.TryGetValue(scenePath, out value))
            {
                return value;
            }

            return -1;
        }

        public string GetScenePathByIndex(int index)
        {
            if (index < 0 || index >= scenesList.Length)
            {
                Debug.LogError("Scene index out of range: " + index);
                return string.Empty;
            }

            return scenesList[index];
        }

        public Scene LoadScene(string scenePath)
        {
            Index = GetSceneIndex(scenePath);
            ToolsHelper.GC();
            RenderTexture.active = null;
            return EditorSceneManager.OpenScene(scenePath);
        }

        public bool SaveScene(Scene scene, string scenePath)
        {
            return EditorSceneManager.SaveScene(scene, scenePath);
        }

        public override void Process()
        {
            ToolsHelper.ShowProgressBar("Scenes Check", "Collecting scenes info", 0.1f);
            GlobalConfig globalConfig = Singleton<ConfigMgr>.Instance.GetConfig<GlobalConfig>() as GlobalConfig;
            scenesDictionary.Clear();
            scenesCheckConfig = (Singleton<ConfigMgr>.Instance.GetConfig<ScenesCheckConfig>() as ScenesCheckConfig);
            string[] files = Directory.GetFiles(Application.dataPath, "*", SearchOption.AllDirectories);
            List<string> list = new List<string>();
            if (scenesCheckConfig.sceneCheckMode == ScenesCheckConfig.e_Scene_Check_Mode.All)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    string text = ToolsHelper.ConvertAbsolutePathToRelative(files[i]);
                    if (!text.EndsWith(".unity") || scenesDictionary.ContainsKey(text) || scenesDictionary.ContainsKey(text))
                    {
                        continue;
                    }

                    bool flag = true;
                    if (globalConfig != null && globalConfig.globalIgnoreConfigs != null)
                    {
                        foreach (ScanAssetsConfig globalIgnoreConfig in globalConfig.globalIgnoreConfigs)
                        {
                            if ((globalIgnoreConfig.matchingType == MatchingType.regex && ToolsHelper.IsMatch(globalIgnoreConfig.assetPath, text)) || (globalIgnoreConfig.matchingType == MatchingType.directory && ToolsHelper.IsDirContain(globalIgnoreConfig.assetPath, text)))
                            {
                                flag = false;
                                break;
                            }
                        }
                    }

                    if (flag)
                    {
                        list.Add(text);
                        scenesDictionary.Add(text, scenesDictionary.Count);
                    }
                }
            }
            else
            {
                EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
                for (int j = 0; j < scenes.Length; j++)
                {
                    if (scenes[j].enabled && scenes[j].path.EndsWith(".unity") && !scenesDictionary.ContainsKey(scenes[j].path))
                    {
                        string path = scenes[j].path;
                        if (!scenesDictionary.ContainsKey(path))
                        {
                            list.Add(path);
                            scenesDictionary.Add(path, scenesDictionary.Count);
                        }
                    }
                }
            }

            scenesList = list.ToArray();
            isProcessed = true;
            isOutputCompleted = false;
        }

        public override void Output()
        {
            if (!isProcessed)
            {
                ScanLog.Instance.LogInfo(Module.Scenes_Check, "EditorSceneManager", "Data has not been setted up. But it is trying to output.");
            }
            else
            {
                if (isOutputCompleted)
                {
                    return;
                }

                StreamWriter streamWriter = Singleton<FileStreamFactory>.Instance.GetStreamWriter(ToolsHelper.GetScanOutPut() + "/scenemap.csv");
                foreach (KeyValuePair<string, int> item in scenesDictionary)
                {
                    streamWriter.WriteLine(item.Value + "," + ToolsHelper.QuoteString(item.Key.Replace("/", "\\")));
                }

                streamWriter.Close();
                isOutputCompleted = true;
                isProcessed = false;
            }
        }
    }
}